<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Mt4 {

	var $socketPtr;
	var $secretHashValue = "none";
	var $encryptionKey = "none";
	var $errno = 0;
	var $errstr = 0;
	var $server = '';
	var $port = '';
	
	function __construct(){
	
	}
	
	function connect($server, $port) {
		if(!function_exists('fsockopen'))
		{	
				$this->errstr = 'fsockopen() function is disabled.';
				return false;
		}
		$this->errstr    = '';
		$this->errno	 = 0;
		$this->server 	 = $server;
		$this->port 	 = $port;
		$this->socketPtr = @fsockopen($this->server, $this->port, $this->errno, $this->errstr, 0.4);
		if(!$this->socketPtr) 	return false;
		else 					return true;
	}
	
	function SetSafetyData($secretHashValue, $encryptionKey) {
		$this->secretHashValue = $secretHashValue;
		$this->encryptionKey = $encryptionKey;
	}
	
	function _parse_answer($answerData) {
		// echo $answerData;
		$result = array();
		$data = explode("&", $answerData);
		foreach($data as $piece)
		{
			$keyval = explode("=", $piece, 2);
			$result[$keyval[0]] = @$keyval[1];
		}
		return $result;
	}
	
	function request($action, $params = array()) {
		if(!$this->socketPtr) 
		{
				if($this->server && $this->port && $this->connect($this->server, $this->port)===FALSE)
				{
						return false;
				}
				if($this->errstr) return false; 
		}
		// $request_id = 6099;//rand();
		$request_id = rand();
		$request = "action=$action&request_id=$request_id";

		foreach($params as $key => $value) {
			$request .= "&$key=$value";
		}		

		if($this->secretHashValue != "none") {
			$hash = $this->makeHash($action, $request_id);
			$request .= "&hash=$hash";
		}

		$request .= "\0"; // leading zero. It must be added to the end of each request		
		if($this->encryptionKey != "none") {
			$request = $this->cryptography($request);			
		}
		
		if($request == "") return "error 2";
		$this->sendRequest($request);

		return $this->_parse_answer($this->readAnswer());
	}

	function disconnect() {
		fclose($this->socketPtr);
	}

	function sendRequest($request) {
		fputs($this->socketPtr, $request);
	}

	function readAnswer() {
		$size = fgets($this->socketPtr, 64);	
			
		$answer = "";			
		$readed = 0;

		while($readed < $size) {
			$part = fread($this->socketPtr, $size - $readed);	
			$readed += strlen($part);
			$answer .= $part;
		}
		if($this->encryptionKey != "none") {
			$answer = $this->cryptography($answer, $encryptionKey);
		}
		return $answer;
	}
		
	function makeHash($action, $request_id) {
		return md5( $request_id . $action . $this->secretHashValue);	
	}

	function cryptography($data) {
		$keyLen = strlen($this->encryptionKey);
		$keyIndex = 0;
		for($i = 0; $i < strlen($data); $i++) {
			$data[$i] = $data[$i] ^ $this->encryptionKey[$keyIndex];
			$keyIndex++;
			if($keyIndex == $keyLen) $keyIndex = 0;
		}
		return $data;
	}

}

/* End of file Mt4.php */